package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.doc.CourseDoc;
import cn.itsource.ymcc.domain.*;
import cn.itsource.ymcc.dto.*;
import cn.itsource.ymcc.feign.CourseSearchFeign;
import cn.itsource.ymcc.feign.MediaSearchFeign;
import cn.itsource.ymcc.mapper.*;
import cn.itsource.ymcc.result.JSONResult;
import cn.itsource.ymcc.service.ICourseService;
import cn.itsource.ymcc.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import cn.itsource.ymcc.feign.SystemFeign;
import org.apache.commons.lang.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Eric Chen
 * @since 2022-07-11
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private CourseDetailMapper courseDetailMapper;
    @Autowired
    private CourseMarketMapper courseMarketMapper;
    @Autowired
    private CourseTeacherMapper courseTeacherMapper;
    @Autowired
    private CourseSummaryMapper courseSummaryMapper;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private SystemFeign systemFeign;
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    private CourseSearchFeign courseSearchFeign;
    @Autowired
    private CourseChapterMapper courseChapterMapper;
    @Autowired
    private MediaSearchFeign mediaSearchFeign;
    @Override
    @Transactional
    public void save(CourseDto dto) {
        Course course = dto.getCourse();
        CourseDetail courseDetail = dto.getCourseDetail();
        CourseMarket courseMarket = dto.getCourseMarket();
        CourseResource courseResource = dto.getCourseResource();
        List<Long> teacharIds = dto.getTeacharIds();

        //姓名校验
        String name = course.getName();
        EntityWrapper<Course> wrapper = new EntityWrapper<>();
        wrapper.eq("name",name);
        Course course1 = selectOne(wrapper);
        AssertUtil.isNull(course1,"名字重复");

        // 课程存储
        course.setStatus(Course.OF_SALE);
        // 获取认证中的登录信息

        SecurityContext context = SecurityContextHolder.getContext();
        Authentication authentication = context.getAuthentication();
        String principal = (String)authentication.getPrincipal();
        Login login = JSON.parseObject(principal,Login.class);


        course.setLoginId(login.getId());
        course.setLoginUserName(login.getUsername());
        course.setTotalMinute(0);
        course.setChapterCount(0);
        course.setOnlineTime(null);
        List<Teacher> teachers = teacherMapper.selectBatchIds(teacharIds);
        List<String> collect = teachers.stream().map(teacher -> {
            return teacher.getName();
        }).collect(Collectors.toList());
        String s = StringUtils.join(collect, ",");
        course.setTeacherNames(s);
        insert(course);

        courseDetail.setId(course.getId());
        courseDetailMapper.insert(courseDetail);

        courseMarket.setId(course.getId());
        courseMarketMapper.insert(courseMarket);

        CourseTeacher courseTeacher = new CourseTeacher();
        for (Long teacharId : teacharIds) {
            courseTeacher.setCourseId(course.getId());
            courseTeacher.setTeacherId(teacharId);
            courseTeacherMapper.insert(courseTeacher);
        }
    }



    @Override
    public Page<Course> selectPage(Page<Course> page) {
        Page<Course> coursePage = super.selectPage(page);
        List<Course> records = coursePage.getRecords();
        HashMap<Long, String> map = (HashMap<Long, String>)redisTemplate.opsForValue().get("Systemdictionaryitem");
        if (map == null){
            JSONResult list = systemFeign.list();
            List<Systemdictionaryitem> data = (List<Systemdictionaryitem>) list.getData();
            String s = JSON.toJSONString(data);
            data = JSON.parseArray(s, Systemdictionaryitem.class);
            map = new HashMap<>();
            for (Systemdictionaryitem datum : data) {
                map.put(datum.getId(),datum.getName());
            }
            redisTemplate.opsForValue().set("Systemdictionaryitem",map);
        }
        for (Course record : records) {
            String sa = map.get(record.getGradeId());
            record.setGradeName(sa);
        }
        return coursePage;
    }


    @Override
    @Transactional // 课程上线保持到es中
    public void onLineCourse(Long id) {
        AssertUtil.isNotNull(id,"没有id");

        Course course = selectById(id);
        AssertUtil.isNotNull(course,"课程不存在");

        //判断状态必须是下线
        AssertUtil.isEquals(course.getStatus() , Course.OF_SALE , "课程已经上线");

        course.setStatus(Course.ON_SALE);
        course.setOnlineTime(new Date());
        updateById(course);

        CourseMarket courseMarket = courseMarketMapper.selectById(id);
        CourseSummary summary = courseSummaryMapper.selectById(id);

        CourseDoc courseDoc = new CourseDoc();
        BeanUtils.copyProperties(course , courseDoc);
        BeanUtils.copyProperties(courseMarket , courseDoc);
        BeanUtils.copyProperties(summary , courseDoc);
        //设置收费方式
        courseDoc.setChargeName(courseMarket.getCharge() == 1?"收费":"免费");
        //保存课程到ES中
        JSONResult jsonResult = courseSearchFeign.save(courseDoc);
        AssertUtil.isTrue(jsonResult.isSuccess(),jsonResult.getMessage());
        sendSms(id);
    }



    public void sendSms(Long id){ // 通过mq发送通知
        StationDto dto = new StationDto(null,"课程发布啦","亲爱的用户您好，最新课程 <a href='javaWEB班j"+id+"'> javaWEB班j </a> 发布啦，点击课程了解详情",
                Arrays.asList(1L,2L,3L));
        String s = JSON.toJSONString(dto);
        rocketMQTemplate.syncSend("message:station",s);
    }


    @Override
    @Transactional // 课程下线并删除es
    public void offLineCourse(Long id) {
        AssertUtil.isNotNull(id,"没有id");

        Course course = selectById(id);
        AssertUtil.isNotNull(course,"课程不存在");

        //判断状态必须是下线
        AssertUtil.isEquals(course.getStatus() , Course.ON_SALE , "课程已经下线");
        course.setStatus(Course.OF_SALE);
        updateById(course);
        JSONResult delete = courseSearchFeign.delete(id);
        AssertUtil.isTrue(delete.isSuccess(),delete.getMessage());
    }

    @Override //课程详细查询
    public CourseDetailData detailData(Long id) {

        AssertUtil.isNotNull(id,"id为空");

        Course course = selectById(id);
        Integer status = course.getStatus();
        AssertUtil.isEquals(status,1,"没上线");

        CourseDetail courseDetail = courseDetailMapper.selectById(id);
        CourseMarket courseMarket = courseMarketMapper.selectById(id);
        CourseSummary courseSummary = courseSummaryMapper.selectById(id);

        EntityWrapper<CourseTeacher> wrapper = new EntityWrapper<>();
        wrapper.eq("course_id",id);
        List<CourseTeacher> courseTeachers = courseTeacherMapper.selectList(wrapper);
        List<Long> ids = courseTeachers.stream().map(e ->
                e.getTeacherId()
        ).collect(Collectors.toList());
        List<Teacher> teachers = teacherMapper.selectBatchIds(ids);

        EntityWrapper<CourseChapter> wrapper1 = new EntityWrapper<>();
        wrapper1.eq("course_id",id);
        List<CourseChapter> chapters = courseChapterMapper.selectList(wrapper1);
        Map<Long, CourseChapter> map = new HashMap<>();
        chapters.forEach(courseChapter -> {
            map.put(courseChapter.getId(),courseChapter);
        });
        JSONResult byCourseId = mediaSearchFeign.getByCourseId(id);
        String s = JSON.toJSONString(byCourseId.getData());
        List<MediaFile> mediaFiles = JSON.parseArray(s, MediaFile.class);
        mediaFiles.forEach(mediaFile -> {
            CourseChapter courseChapter = map.get(mediaFile.getChapterId());
            if (courseChapter!=null)courseChapter.getMediaFiles().add(mediaFile);
        });

        return new CourseDetailData(course,courseMarket,courseSummary,courseDetail,teachers,chapters);
    }

    @Override //课程表单详细查询
    public CourseOrderDto info(String id) {
        String[] ids = id.split(",");
        List<Course> courses = selectBatchIds(Arrays.asList(ids));
        List<CourseInfo> list = new ArrayList<>();
        BigDecimal decimal = new BigDecimal("0");
        for (Course course : courses) {
            AssertUtil.isEquals(course.getStatus(), Course.ON_SALE, "没上线");
            CourseMarket courseMarket = courseMarketMapper.selectById(course.getId());
            CourseInfo info = new CourseInfo(course, courseMarket);
            list.add(info);
            decimal = decimal.add(courseMarket.getPrice());
        }
        return new CourseOrderDto(list,decimal);
    }

    public CourseOrderDto infoKill(String id,String orderNo){
        Long loginId = 3L;
        Course course = selectById(Long.valueOf(id));
        String orderKey = "order:"+loginId+":"+orderNo;
        KillOrderDto killOrderDto = (KillOrderDto)redisTemplate.opsForValue().get(orderKey);

        //Course course1 = selectById(killOrderDto.getCourseId());

        List<CourseInfo> list = new ArrayList<>();
        BigDecimal totalAmount = killOrderDto.getTotalAmount();
        CourseMarket courseMarket = courseMarketMapper.selectById(Long.valueOf(id));
        courseMarket.setPrice(totalAmount);
        AssertUtil.isEquals(course.getStatus(), Course.ON_SALE, "没上线");
        CourseInfo info = new CourseInfo(course, courseMarket);
        list.add(info);
        return new CourseOrderDto(list,totalAmount);
    }
}
